package composite

import (
	"fmt"
	"strings"
)

// 定义员工接口
type Employee interface {
	GetSalary() float64
	GetResponsibilities() string
	ReportTo() string
	AddSubordinate(Employee)
	RemoveSubordinate(Employee)
	GetSubordinates() []Employee
	String() string
}

// 实现具体的员工类
type RegularEmployee struct {
	name             string
	salary           float64
	responsibilities string
	reportTo         string
	subordinates     []Employee
}

func NewRegularEmployee(name string, salary float64, responsibilities string, reportTo string) *RegularEmployee {
	return &RegularEmployee{
		name:             name,
		salary:           salary,
		responsibilities: responsibilities,
		reportTo:         reportTo,
		subordinates:     make([]Employee, 0),
	}
}

func (e *RegularEmployee) GetSalary() float64 {
	return e.salary
}

func (e *RegularEmployee) GetResponsibilities() string {
	return e.responsibilities
}

func (e *RegularEmployee) ReportTo() string {
	return e.reportTo
}

func (e *RegularEmployee) AddSubordinate(emp Employee) {
	e.subordinates = append(e.subordinates, emp)
}

func (e *RegularEmployee) RemoveSubordinate(emp Employee) {
	for i, subordinate := range e.subordinates {
		if subordinate == emp {
			e.subordinates = append(e.subordinates[:i], e.subordinates[i+1:]...)
			break
		}
	}
}

func (e *RegularEmployee) GetSubordinates() []Employee {
	return e.subordinates
}

func (e *RegularEmployee) String() string {
	return fmt.Sprintf("Name: %s, Salary: %.2f, Responsibilities: %s, Report To: %s", e.name, e.salary, e.responsibilities, e.reportTo)
}

type Manager struct {
	name             string
	salary           float64
	responsibilities string
	reportTo         string
	subordinates     []Employee
}

func NewManager(name string, salary float64, responsibilities string, reportTo string) *Manager {
	return &Manager{
		name:             name,
		salary:           salary,
		responsibilities: responsibilities,
		reportTo:         reportTo,
		subordinates:     make([]Employee, 0),
	}
}

func (m *Manager) GetSalary() float64 {
	return m.salary
}

func (m *Manager) GetResponsibilities() string {
	return m.responsibilities
}

func (m *Manager) ReportTo() string {
	return m.reportTo
}

func (m *Manager) AddSubordinate(emp Employee) {
	m.subordinates = append(m.subordinates, emp)
}

func (m *Manager) RemoveSubordinate(emp Employee) {
	for i, subordinate := range m.subordinates {
		if subordinate == emp {
			m.subordinates = append(m.subordinates[:i], m.subordinates[i+1:]...)
			break
		}
	}
}

func (m *Manager) GetSubordinates() []Employee {
	return m.subordinates
}

func (m *Manager) String() string {
	return fmt.Sprintf("Name: %s, Salary: %.2f, Responsibilities: %s, Report To: %s", m.name, m.salary, m.responsibilities, m.reportTo)
}

type Company struct {
	employees []Employee
}

func NewCompany() *Company {
	return &Company{
		employees: make([]Employee, 0),
	}
}

func (c *Company) AddEmployee(emp Employee) {
	c.employees = append(c.employees, emp)
}

func (c *Company) RemoveEmployee(emp Employee) {
	for i, employee := range c.employees {
		if employee == emp {
			c.employees = append(c.employees[:i], c.employees[i+1:]...)
			break
		}
	}
}

func (c *Company) GetEmployees() []Employee {
	return c.employees
}

func (c *Company) String() string {
	var sb strings.Builder
	for _, emp := range c.employees {
		sb.WriteString(emp.String())
		sb.WriteString("\n")
	}
	return sb.String()
}
